package com.xnx3.j2ee.util.actionLog;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import com.aliyun.openservices.log.common.LogContent;
import com.aliyun.openservices.log.common.LogItem;
import com.aliyun.openservices.log.exception.LogException;
import com.xnx3.j2ee.Global;
import com.xnx3.j2ee.util.ActionLogUtil;
import com.xnx3.j2ee.util.ConsoleUtil;
import com.xnx3.j2ee.util.Page;
import com.xnx3.j2ee.util.SystemUtil;
import com.xnx3.j2ee.vo.ActionLogListVO;
import com.xnx3.net.AliyunLogPageUtil;
import com.xnx3.net.AliyunLogUtil;
import net.sf.json.JSONArray;

/**
 * 日志记录，使用阿里云日志服务
 * @author 管雷鸣
 *
 */
public class AliyunSLSMode implements ActionLogInterface{
	public static AliyunLogUtil aliyunLogUtil = null;
	static String keyId;
	static String keySecret;
	static String endpoint;
	static String project;
	
	static{
		new Thread(new Runnable() {
			@Override
			public void run() {
				while(Global.system.size() < 1){
					try {
						Thread.sleep(1000);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}
				
				//判断 actionLogInterface 接口当前是否已经使用了其他的方法初始化。优先以elasticsearch为主
				if(ActionLogUtil.actionLogInterface != null){
					//已经使用了 ElasticSearch，那么就不再使用这个阿里云日志服务了
					return;
				}
				
				//当数据库加载完后，再初始化
				//判断是否使用日志服务进行日志记录，条件便是 accessKeyId 是否为空。若为空，则不使用
				String use = SystemUtil.get("ALIYUN_SLS_USE");
				if(use != null && use.equals("1")){
					//使用日志服务
					
					keyId = SystemUtil.get("ALIYUN_ACCESSKEYID");
					keySecret = SystemUtil.get("ALIYUN_ACCESSKEYSECRET");
					endpoint = SystemUtil.get("ALIYUN_SLS_ENDPOINT");
					project = SystemUtil.get("ALIYUN_SLS_PROJECT");
					String logstore = SystemUtil.get("ALIYUN_SLS_USERACTION_LOGSTORE");
					
					//最大超时时间
					int log_cache_max_time = SystemUtil.getInt("ALIYUN_SLS_CACHE_MAX_TIME");
					if(log_cache_max_time == 0){
						log_cache_max_time = 120;
					}
					//最大条数
					int log_cache_max_number = SystemUtil.getInt("ALIYUN_SLS_CACHE_MAX_NUMBER");
					if(log_cache_max_number == 0){
						log_cache_max_number = 100;
					}
					
					
					if(keyId.length() > 10){
						aliyunLogUtil = new AliyunLogUtil(endpoint,  keyId, keySecret, project, logstore);
						//开启触发日志的，其来源类及函数的记录
						aliyunLogUtil.setStackTraceDeep(5);
						aliyunLogUtil.setCacheAutoSubmit(log_cache_max_number, log_cache_max_time);
						ConsoleUtil.info("开启阿里云日志服务进行操作记录");
					}else{
						//此处可能是还没执行install安装
					}
					
					ActionLogUtil.actionLogInterface = new AliyunSLSMode();
				}
				
				/*
				 *  ActionLogUtil.aliyunLogUtil 废弃,这里只是向上兼容而已
				 */
				ActionLogUtil.aliyunLogUtil = AliyunSLSMode.aliyunLogUtil;
				
			}
		}).start();
		
		
	}

	@Override
	public void add(Map<String, Object> map) {
		if(aliyunLogUtil == null){
			//不使用日志服务，终止即可
			return;
		}
		
		//将map转化为 logitem
		LogItem logItem = aliyunLogUtil.newLogItem();
		for(Map.Entry<String, Object> entry : map.entrySet()){
			String value = null;
			if(entry.getValue() == null){
				value = "";
			}else{
				value = entry.getValue().toString()+"";
			}
			logItem.PushBack(entry.getKey(), value);
		}
		
		try {
			aliyunLogUtil.cacheLog(logItem);
		} catch (LogException e) {
			e.printStackTrace();
		}
	}
	
	/**
	 * 将 {@link LogItem} 转化为 {@link Map}
	 */
	public static Map<String, Object> logitemToMap(LogItem logItem){
		if(logItem == null){
			return null;
		}
		Map<String, Object> map = new HashMap<String, Object>();
		ArrayList<LogContent> array = logItem.GetLogContents();
		for (int i = 0; i < array.size(); i++) {
			LogContent log = array.get(i);
			map.put(log.GetKey(), log.GetValue());
		}
		return map;
	}

	@Override
	public boolean cacheCommit() {
		if(aliyunLogUtil != null){
			try {
				if(aliyunLogUtil.logGroupCache.size() > 0){
					//如果有日志，那么自动提交日志
					aliyunLogUtil.cacheCommit();
				}
			} catch (Exception e) {
				e.printStackTrace();
				return false;
			}
		}
		
		return true;
	}

	@Override
	public ActionLogListVO list(String query, int everyPageNumber, HttpServletRequest request) {
		AliyunLogPageUtil log = new AliyunLogPageUtil(aliyunLogUtil);
		return list(log, query, everyPageNumber, request);
	}

	@Override
	public ActionLogListVO list(String indexName, String query, int everyPageNumber, HttpServletRequest request) {
		AliyunLogPageUtil log = new AliyunLogPageUtil(endpoint, keyId, keySecret, project, indexName);
		return list(log, query, everyPageNumber, request);
	}
	
	private ActionLogListVO list(AliyunLogPageUtil aliyunLogPageUtil, String query, int everyPageNumber, HttpServletRequest request){
		//得到当前页面的列表数据
		JSONArray jsonArray = null;
		try {
			jsonArray = aliyunLogPageUtil.list(query, "", true, everyPageNumber, request);
		} catch (LogException e) {
			e.printStackTrace();
		}
		if(jsonArray == null){
			jsonArray = new JSONArray();
		}
		//得到当前页面的分页相关数据（必须在执行了list方法获取列表数据之后，才能调用此处获取到分页）
		Page page = aliyunLogPageUtil.getPage();
		
		ActionLogListVO vo = new ActionLogListVO();
		vo.setJsonArray(jsonArray);
		vo.setPage(page);
		
		return vo;
	}
}
